package com.duoec.dw.lineage.service.analyser.field;

import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
import com.duoec.dw.lineage.core.utils.AnalyserUtils;
import com.duoec.dw.lineage.dto.MultiTableLineageDto;
import com.duoec.dw.lineage.dto.TableFieldLineageDto;
import com.duoec.dw.lineage.dto.TableInfoDto;
import com.duoec.dw.lineage.dto.TableLineageDto;
import com.duoec.dw.lineage.service.LineageTableService;
import com.duoec.dw.lineage.service.analyser.HiveSelectFieldAnalyser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.LinkedHashSet;

/**
 * @author xuwenzhen
 */
@Service
public class PropertyFieldAnalyser extends BaseFieldAnalyser<SQLPropertyExpr> {
    public static final String ALL_FIELDS = "*";

    @Autowired
    private LineageTableService lineageTableService;

    @Autowired
    @Qualifier("defaultFieldAnalyser")
    private HiveSelectFieldAnalyser defaultFieldAnalyser;

    /**
     * 当前类处理的类型
     *
     * @return SQLExpr的子类
     */
    @Override
    public Class<SQLPropertyExpr> getSelectFieldType() {
        return SQLPropertyExpr.class;
    }

    /**
     * 解析 select
     *
     * @param selectFieldExpr   需要解析的select field
     * @param tableLineage      当前表的血缘关系信息
     * @param fromTableLineages 当前查询依赖字段的多表血缘关系
     */
    @Override
    public LinkedHashSet<TableFieldLineageDto> analyse(SQLPropertyExpr selectFieldExpr, TableLineageDto tableLineage, MultiTableLineageDto fromTableLineages) {
        String fieldName = selectFieldExpr.getName();
        if (ALL_FIELDS.equals(fieldName)) {
            // t.*
            LinkedHashSet<TableFieldLineageDto> fields = tableLineage.getFields();
            TableLineageDto selectTableLineage = fromTableLineages.getTable(selectFieldExpr.getOwnernName());
            if (CollectionUtils.isEmpty(selectTableLineage.getFields())) {
                TableInfoDto table = lineageTableService.getTableDto(selectTableLineage);
                LinkedHashSet<TableFieldLineageDto> fieldLineages = AnalyserUtils.setTableLineageAllFields(table, fromTableLineages);
                fieldLineages.forEach(field -> {
                    field.setIndex(fields.size());
                    fields.add(field);
                });
                return fieldLineages;
            } else {
                //直接使用当前的数据
                return mergeFieldLineages(fields, selectTableLineage.getFields());
            }
        }

        //其它
        return defaultFieldAnalyser.analyse(selectFieldExpr, tableLineage, fromTableLineages);
    }

    public void setDefaultFieldAnalyser(HiveSelectFieldAnalyser defaultFieldAnalyser) {
        this.defaultFieldAnalyser = defaultFieldAnalyser;
    }
}
